<template>
    <div v-show="!isCrop" class="DetailBox">
        <div class="back" @click="back" v-if="rightClickFunction != 'Back' && rightClickFunction != 'Menu'">
            <el-icon :size="25">
                <Back />
            </el-icon>
        </div>
        <div class="moveToTheLeft" @click="changeIndex(-1)">
            <div class="itemChange">
                <el-icon>
                    <ArrowLeftBold />
                </el-icon>
            </div>
        </div>
        <imgLoading v-show="!successLoading" class="loadingAnimation"></imgLoading>
        <imgError class="errorImg" v-show="loadingError"></imgError>
        <img v-show="successLoading && !loadingError" :src="urls[showImgIndex].source" class="elImg" alt=""
            @click="viewImg(urls[showImgIndex].source)" @load="imgLoadEvent" @error="imgErrorEvent" />
        <div class="moveToTheRight" @click="changeIndex(1)">
            <div class="itemChange">
                <el-icon>
                    <ArrowRightBold />
                </el-icon>
            </div>
        </div>
        <div class="tools" v-if="rightClickFunction != 'Menu'">
            <div class="item" title="设为壁纸" @click="downloadTheOriginalImage(true)">
                <el-icon>
                    <Picture />
                </el-icon>
            </div>
            <div class="item" title="下载原图" @click="downloadTheOriginalImage(false)">
                <el-icon>
                    <Download />
                </el-icon>
            </div>
            <div class="item" title="复制链接" @click="copyUrl">
                <el-icon>
                    <Share />
                </el-icon>
            </div>
            <div :class="{ item: true }" title="添加收藏" @click="addToFavorites"
                v-if="collectionImgs.findIndex((item: any) => item.source == urls[showImgIndex].source) == -1">
                <el-icon>
                    <StarFilled color="#fff" />
                </el-icon>
            </div>
            <div :class="{ item: true, active: true }" title="取消收藏" @click="addToFavorites" v-else>
                <el-icon>
                    <StarFilled color="#f9f871" />
                </el-icon>
            </div>
            <div class="item" title="图片裁剪" @click="CropImg">
                <el-icon>
                    <Crop />
                </el-icon>
            </div>
        </div>
        <el-image-viewer @close="closeImgViewer" v-if="showViewer" :url-list="previewList" :max-scale="7"
            :min-scale="0.5" />
        <div class="menu" ref="menu" @click="menuClick">
            <div class="menuItem" @click="downloadTheOriginalImage(true)">
                <el-icon>
                    <Picture />
                </el-icon>
                <text>设为壁纸</text>
            </div>
            <div class="menuItem" @click="downloadTheOriginalImage(false)">
                <el-icon>
                    <Download />
                </el-icon>
                <text>下载原图</text>
            </div>
            <hr>
            <div class="menuItem" @click="copyUrl">
                <el-icon>
                    <Share />
                </el-icon>
                <text>复制链接</text>
            </div>
            <div class="menuItem">
                <el-icon>
                    <StarFilled />
                </el-icon>
                <text> 收藏壁纸</text>
            </div>
            <hr>
            <div class="menuItem" @click="CropImg">
                <el-icon>
                    <Crop />
                </el-icon>
                <text>图片裁剪</text>
            </div>
            <div class="menuItem" @click="back">
                <el-icon>
                    <Back />
                </el-icon>
                <text>返回上级</text>
            </div>
        </div>
    </div>
    <cropComponent v-if="isCrop" :cropSource="urls[showImgIndex].source" @cropClose="cropClose"></cropComponent>
</template>

<script setup lang="ts">
import { Back, ArrowLeftBold, ArrowRightBold, Download, Share, StarFilled, Picture, Crop } from '@element-plus/icons-vue'
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
import { settingStore } from '@renderer/store/setting'
import { storeToRefs } from 'pinia'
import { ElMessage } from 'element-plus'
import imgLoading from './theme/imgLoading.vue'
import imgError from './theme/imgError.vue'
import cropComponent from './crop.vue'
const { ipcRenderer } = require('electron')
let myApi
const set = settingStore()
const { downloadLocation, historyImgs, rightClickFunction, imgFormat, collectionImgs } = storeToRefs(set)
const showImgIndex = ref<number>(0)
const $emits = defineEmits(['closePicture'])
const showViewer = ref(false)
const previewList = ref<string[]>([])
const successLoading = ref(false)
const loadingError = ref(false)
const menu = ref<HTMLElement | null>(null)
const isCrop = ref(false)

const props = defineProps({
    urls: {
        type: Array as any,
        default: []
    },
    index: {
        type: Number,
        default: 0
    },
    collection: {
        type: Boolean,
        default: false
    }
})
const addToFavorites = () => {
    if (props.collection) $emits('closePicture')
    set.addCollectionImgs(props.urls[showImgIndex.value])
    ipcRenderer.send('update-storage', JSON.stringify(set.$state))
}
const viewImg = (src: string) => {
    menu.value!.style.display = 'none'
    previewList.value = [src]
    showViewer.value = true
}
const imgLoadEvent = () => {
    successLoading.value = true
    loadingError.value = false
}
const imgErrorEvent = () => {
    loadingError.value = true
    successLoading.value = true
}

const back = () => {
    $emits('closePicture')
}

const changeIndex = (index: number) => {
    successLoading.value = false
    loadingError.value = false
    showImgIndex.value += index
    if (showImgIndex.value < 0) {
        showImgIndex.value = props.urls.length - 1
    } else if (showImgIndex.value > props.urls.length - 1) {
        showImgIndex.value = 0
    }
}

const downloadTheOriginalImage = (setWallpaper: boolean = false) => {
    const elImg = document.querySelector('.elImg') as HTMLImageElement
    // 创建一个隐藏的canvas元素
    const canvas = document.createElement('canvas')
    const ctx = canvas.getContext('2d')!
    // 设置canvas的尺寸与图片原始尺寸一致
    canvas.width = elImg.naturalWidth
    canvas.height = elImg.naturalHeight
    // 将图片绘制到canvas上
    ctx.drawImage(elImg, 0, 0, elImg.naturalWidth, elImg.naturalHeight)
    // 异步保存图片 避免主线程阻塞
    setTimeout(() => {
        // 获取canvas的Base64编码数据，指定格式为jpg
        const base64Data = canvas.toDataURL(imgFormat.value)
        // 从Base64数据中提取图片格式信息
        const imageFormat = imgFormat.value == 'image/png' ? 'png' : 'jpg'
        // 后续可以根据提取出的图片格式和保存路径等信息进行保存图片等操作
        // 例如，以下是简单示意如何拼接正确的文件名用于保存（假设已经导入了path模块）
        const fs = require('fs')
        const path = require('path')
        if (!fs.existsSync(downloadLocation.value)) {
            try {
                fs.mkdirSync(downloadLocation.value);
            } catch (err) {
                ElMessage({
                    message: '创建下载文件夹失败：' + err,
                    type: 'error',
                    plain: true,
                })
                return
            }
        }
        const name = setWallpaper == true ? 'desktopWallpaper' : Date.now()
        const fileName = `${name}.${imageFormat}`
        const fullPath = path.join(downloadLocation.value, fileName)
        fs.writeFile(fullPath, Buffer.from(base64Data.replace(/^data:image\/\w+;base64,/, ''), 'base64'), async (err) => {
            if (err) {
                ElMessage({
                    message: '保存失败' + err,
                    type: 'error',
                    plain: true,
                })
            } else {
                if (setWallpaper == true) {
                    const obj = { path: fullPath }
                    await myApi.setWallpaper(obj)
                    ElMessage({
                        message: '设置成功',
                        type: 'success',
                        plain: true,
                    })
                } else {
                    ElMessage({
                        message: '保存成功',
                        type: 'success',
                        plain: true,
                    })
                }
            }
        })
    }, 0)
}

const copyUrl = () => {
    // 把链接复制到剪贴板
    let url = props.urls[showImgIndex.value].source

    myApi.copyToClipboard(url)
    ElMessage({
        message: '复制成功',
        type: 'success',
        plain: true,
    })
}


const keyboardEvents = (e) => {
    const left = document.querySelector('.moveToTheLeft')!
    const right = document.querySelector('.moveToTheRight')!
    if (e.key === 'ArrowRight') {
        changeIndex(1)
        right.setAttribute('style', 'background-color: #1961fe;color: #fff;')
        setTimeout(() => {
            right.setAttribute('style', 'background-color: none;color: none;')
        }, 300)
    } else if (e.key === 'ArrowLeft') {
        changeIndex(-1)
        left.setAttribute('style', 'background-color: #1961fe;color: #fff;')
        setTimeout(() => {
            left.setAttribute('style', 'background-color: none;color: none;')
        }, 300)
    }
}

const change = () => {
    menu.value!.style.display = 'none'
    const exits = historyImgs.value.findIndex((item) => item.src === props.urls[showImgIndex.value].src)
    const obj = props.urls[showImgIndex.value]
    if (exits === -1) {
        if (historyImgs.value.length > 30) {
            // 删除最后一个
            historyImgs.value.pop()
            historyImgs.value.unshift(obj)
        } else {
            historyImgs.value.unshift(obj)
        }
    }
    ipcRenderer.send('update-storage', JSON.stringify(set.$state))
}
const CropImg = () => {
    isCrop.value = true
}
const cropClose = () => {
    isCrop.value = false
}
const rightClickEvent = (e) => {
    e.preventDefault()
    if (rightClickFunction.value === "None") return
    if (rightClickFunction.value === "Back") {
        $emits('closePicture')
    }
    if (rightClickFunction.value === "Menu") {
        // 获取当前鼠标位置
        const x = e.clientX
        const y = e.clientY

        if (menu.value!.style.display == 'block') {
            menu.value!.style.display = 'none'
            return
        }
        menu.value!.style.display = 'block'
        menu.value!.style.left = `${x}px`
        menu.value!.style.top = `${y}px`
        // 判断menu边界问题
        if (x + menu.value!.offsetWidth > window.innerWidth) {
            menu.value!.style.left = `${x - menu.value!.offsetWidth}px`
        }
        if (y + menu.value!.offsetHeight > window.innerHeight) {
            menu.value!.style.top = `${y - menu.value!.offsetHeight}px`
        }
    }
}
const menuClick = () => {
    if (menu.value) menu.value.style.display = 'none'
}
const closeImgViewer = () => {
    showViewer.value = false
    menu.value!.style.display = 'none'
}
watch(() => showImgIndex.value, () => {
    change()
})
onMounted(() => {
    myApi = window.api as any
    showImgIndex.value = props.index
    // 监听键盘事件
    document.addEventListener('keydown', keyboardEvents)
    change()

    // 监听右键事件
    document.addEventListener('contextmenu', rightClickEvent)
})
onBeforeUnmount(() => {
    // 移除键盘事件
    document.removeEventListener('keydown', keyboardEvents)
    // 移除右键事件
    document.removeEventListener('contextmenu', rightClickEvent)
})
</script>

<style scoped lang="scss">
.DetailBox {
    width: 100%;
    height: 100vh;
    overflow: hidden;
    position: relative;

    .back {
        top: 5px;
        left: 5px;
        width: 40px;
        height: 40px;
        z-index: 10;
        cursor: pointer;
        position: absolute;
        background-color: #8080804c;
        border-radius: 50%;
        color: #fff;
        transition: all 0.3s;
        display: flex;
        justify-content: center;
        align-items: center;

        &:hover {
            background-color: #1961fe;
            color: white;
        }
    }

    .moveToTheLeft,
    .moveToTheRight {
        position: absolute;
        z-index: 10;
        width: 40px;
        height: 40px;
        display: flex;
        justify-content: center;
        align-items: center;
        border-radius: 50%;
        border: 1px solid #8080804c;
        background-color: #8080804c;
        color: #fff;
        cursor: pointer;
        font-size: 18px;
        top: 50%;
        transform: translateY(-50%);
        transition: all 0.3s;
        opacity: 0;



        &:hover {
            color: #fff;
            border-color: #1961fe;
            background-color: #1961fe;
        }
    }

    &:hover {

        .moveToTheLeft,
        .moveToTheRight {
            opacity: 1;
        }
    }

    .moveToTheLeft {
        left: 20px;
    }

    .moveToTheRight {
        right: 20px;
    }

    .tools {
        text-align: center;
        padding: 5px;
        position: absolute;
        bottom: 50px;
        z-index: 10;
        left: 50%;
        background-color: #ffffff61;
        transform: translateX(-50%);
        transition: all 0.3s;
        display: flex;
        justify-content: center;
        align-items: center;
        gap: 10px;
        border-radius: 8px;
        box-shadow: rgba(99, 99, 99, 0.1) 0px 2px 8px 0px;
        margin-bottom: 1rem;
        border: 3px dashed transparent;

        .item {
            height: 32px;
            width: 32px;
            margin: 0;
            font-size: 20px;
            box-shadow: 0px 0px 2px white;
            border-radius: 50%;
            display: flex;
            justify-content: center;
            align-items: center;
            cursor: pointer;
            color: white;
            transition: all 0.5s;
            box-shadow: 0.3em 0.3em 0.7em #00000015;
            transition: border 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);

            &:nth-child(1) {
                background-color: #1961fe;
            }

            &:nth-child(2) {
                background-color: #00c22d;
            }

            &:nth-child(3) {
                background-color: #00d2fc;
            }

            &:nth-child(4) {
                background-color: #b0a8b9;
            }

            &:nth-child(5) {
                background-color: #7211e0;
            }

            &:hover {
                opacity: 0.8;
            }
        }

        .active {
            background-color: orangered !important;
        }
    }

    .loadingAnimation {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
    }

    .errorImg {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
    }

    .elImg {
        width: 100%;
        height: 100vh;
        user-select: none;
        object-fit: contain;
    }

    .Progress {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        z-index: 100;
    }
}

:deep(.demo-progress) {
    .el-progress--line {
        margin-bottom: 15px;
        max-width: 600px;
    }

    .el-progress--circle {
        margin-right: 15px;
    }
}

.menu {
    width: 110px;
    position: fixed;
    top: 100px;
    left: 100px;
    z-index: 100;
    background-color: #251f2bd4;
    border: 2px solid #b1b1b153;
    color: #fff;
    border-radius: 5px;
    overflow: hidden;
    display: none;

    .menuItem {
        margin: 5px;
        text-align: center;
        cursor: pointer;
        font-size: 15px;
        transition: all 0.3s;
        border-radius: 10px;
        display: flex;
        gap: 4px;
        justify-content: center;
        align-items: center;
        padding: 1px 2px;

        &:last-child {
            border-bottom: none;
        }

        &:hover {
            background-color: #1961fe;
            color: #fff;
        }
    }

    hr {
        border-color: #b1b1b153;
    }
}
</style>